package mx.itesm.rmroman.demoae;

import android.util.Log;

import org.andengine.engine.camera.Camera;
import org.andengine.engine.options.EngineOptions;
import org.andengine.engine.options.ScreenOrientation;
import org.andengine.engine.options.resolutionpolicy.FillResolutionPolicy;
import org.andengine.entity.modifier.MoveByModifier;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.SpriteBackground;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.touch.TouchEvent;
import org.andengine.opengl.texture.ITexture;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.atlas.bitmap.BuildableBitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.source.IBitmapTextureAtlasSource;
import org.andengine.opengl.texture.atlas.buildable.builder.BlackPawnTextureAtlasBuilder;
import org.andengine.opengl.texture.atlas.buildable.builder.ITextureAtlasBuilder;
import org.andengine.opengl.texture.bitmap.AssetBitmapTexture;
import org.andengine.opengl.texture.region.ITextureRegion;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.texture.region.TextureRegionFactory;
import org.andengine.opengl.texture.region.TiledTextureRegion;
import org.andengine.ui.activity.SimpleBaseGameActivity;

import java.io.IOException;

/*
HISTORIA.
1. Proyecto HolaMundo (sin andengine)
2. Proyecto base con andengine
3. Imagen de fondo
4. Banana animada
5. Agregamos reconocimiento de eventos de touch y modificadores
6. Agregamos un MENU con botón responsivo
7. Pendiente
 */

/**
 * Ejemplo de algunas características de AndEngine
 *
 * @author Roberto Martínez Román
 */
public class Principal extends SimpleBaseGameActivity implements IOnSceneTouchListener // Esta clase juega el rol de touchListener
{
    // La camara que muestra el contenido en la pantalla
    private Camera camara;
    // Dimensiones de la cámara, esto lo hace independiente del dispositivo físico
    private static final int ANCHO_CAMARA = 800;
    private static final int ALTO_CAMARA = 480;

    // Variables para la imagen de fondo
    private ITexture texturaFondo;
    private ITextureRegion regionFondo;

    // Variables para las imágenes del sprite animado
    private BuildableBitmapTextureAtlas texturaAtlasBanana;
    private TiledTextureRegion regionTiledBanana;

    // Variable de instancia para guardar el Sprite animado
    private Sprite spriteUno;

    // *** Variable para las imágenes del botón (2x1)
    ITiledTextureRegion regionBotonJugar;

    /**
     * Crea las imágenes/audios que utilizará el juego
     * @throws IOException si algún archivo no existe
     */
    @Override
    protected void onCreateResources() throws IOException {
        // Carga la imagen de fondo
        texturaFondo = new AssetBitmapTexture(getTextureManager(),
                getAssets(),"nuevoLogoTransp.png");
        regionFondo = TextureRegionFactory.extractFromTexture(texturaFondo);
        texturaFondo.load();
        // fin de carga la imagen de fondo

        // Carga las imágenes para el sprite animado
        texturaAtlasBanana = new BuildableBitmapTextureAtlas(getTextureManager(),500,360);
        regionTiledBanana = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(
                texturaAtlasBanana,this,"tileset.png",5,3);
        try {
            texturaAtlasBanana.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0,0,0));
        } catch (ITextureAtlasBuilder.TextureAtlasBuilderException e) {
            Log.d("onCreateResources","No se puede cargar la imagen para el Sprite animado");
        }
        texturaAtlasBanana.load();
        // fin de carga imágenes para el sprite animado

        // ***** Carga las imágenes del botón
        BuildableBitmapTextureAtlas bta = new BuildableBitmapTextureAtlas(getTextureManager(),
                256,128);
        regionBotonJugar = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(
                bta,getAssets(),"btnJugarDos.png",2,1);
        try {
            bta.build(new BlackPawnTextureAtlasBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(0,0,0));
        } catch (ITextureAtlasBuilder.TextureAtlasBuilderException e) {
            Log.println(1,"onCreateResources","No se puede cargar btnJugarDos.png");
        }
        bta.load();
        // ***** Termina carga de imágenes del botón
    }


    /**
     * En este método se crea la escena inicial
     * @return la escena primera
     */
    @Override
    protected Scene onCreateScene() {
        // Un objeto para mostrar los elementos gráficos sobre la pantalla
        Scene escena = new Scene();

        // Crea el sprite que representa la imagen de fondo
        Sprite spriteFondo = new Sprite(ANCHO_CAMARA/2, ALTO_CAMARA/2,  // Centrado
                regionFondo,    // De esta variable toma la imagen
                getVertexBufferObjectManager());

        // Un objeto especial para manejar el fondo de la escena
        SpriteBackground spriteFondoEscena = new SpriteBackground(0.9f,0.4f,0,spriteFondo);

        // Lo asignamos a esta escena
        escena.setBackground(spriteFondoEscena);
        escena.setBackgroundEnabled(true);

        // Ahora creamos el Sprite animado
        AnimatedSprite spriteAnimadoBanana = new AnimatedSprite(ANCHO_CAMARA/2,ALTO_CAMARA/2,
                regionTiledBanana,getVertexBufferObjectManager());

        // Arreglo de tiempos para los frames
        long tiempos[] = new long[6];
        for(int i=0; i<tiempos.length; i++) {
            tiempos[i] = 84;
        }
        // Tiempo entre frames

        spriteAnimadoBanana.animate(tiempos,0,5,true);


        // Agrega el SpriteAnimado a la escena
        escena.attachChild(spriteAnimadoBanana);

        // Guardamos la referencia para modificar el sprite después
        spriteUno = spriteAnimadoBanana;

        // La escena se registra para que se atiendas sus eventos
        escena.setOnSceneTouchListener(this);

        // ***** Agrega botones a la escena
        escena.setTouchAreaBindingOnActionDownEnabled(true); // Habilita touch en áreas
        ButtonSprite btnJugar = new ButtonSprite(ANCHO_CAMARA/4,ALTO_CAMARA/2,regionBotonJugar,getVertexBufferObjectManager()) {
            @Override
            public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                Log.println(1,"onAreaTouched","Botón JUGAR oprimido");
                if ( pSceneTouchEvent.isActionDown() ) {
                    Log.println(1,"onAreaTouched","Botón JUGAR DOWN...");
                }
                return super.onAreaTouched(pSceneTouchEvent, pTouchAreaLocalX, pTouchAreaLocalY);
            }
        };

        escena.registerTouchArea(btnJugar);
        escena.attachChild(btnJugar);

        // Regresamos la escena ya configurada
        return escena;
    }

    /**
     * Crea las opciones para el engine
     * @return opciones con la configuración deseada
     */
    @Override
    public EngineOptions onCreateEngineOptions() {
        camara = new Camera(0, 0, ANCHO_CAMARA, ALTO_CAMARA);
        EngineOptions engineOptions = new EngineOptions(true,
                ScreenOrientation.LANDSCAPE_FIXED, new FillResolutionPolicy(), camara);
        return engineOptions;
    }

    @Override
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {

        if (pSceneTouchEvent.isActionDown() ) {

            // Si se toca en la parte izquierda de la pantalla,
            // el movimiento del sprite será a la izquierda, si no a la derecha
            int dx = -200;  // suponemos que será a la izquierda
            if (pSceneTouchEvent.getX()>ANCHO_CAMARA/2) { // o a la derecha??
                dx = 200;
            }
            // Desplazar el objeto cierta distancia
            MoveByModifier modificador = new MoveByModifier(1,dx,0);

            /*
            // Si se toca en la parte izquierda de la pantalla,
            // aparece, si no desaparece
            int inicio = 0;  // suponemos que aparece
            int fin = 1;
            if (pSceneTouchEvent.getX()>ANCHO_CAMARA/2) { // o desaparece??
                inicio = 1;
                fin = 0;
            }

            // Ocultar el objeto cambiando el alpha
            AlphaModifier modificador = new AlphaModifier(2,inicio,fin);
            */

            /*
            // Si se toca en la parte izquierda de la pantalla,
            // salta a la izq., si no salta a la derecha
            int dx = -100;   // suponemos que va a la izq.
            spriteUno.setFlipped(true,false);   // Invierte la imagen horizontal, vertical
            if (pSceneTouchEvent.getX()>ANCHO_CAMARA/2) { // a la derecha?
                dx = 100;
                spriteUno.setFlipped(false,false);
            }
            // Ejecutar un salto
            JumpModifier modificador = new JumpModifier(1,spriteUno.getX(),spriteUno.getX()+dx,
                    spriteUno.getY(),spriteUno.getY(),-Math.abs(2*dx));
            */

            /*
            // Secuencia de modificadores, a la derecha crece a la izq decrece
            int dx = -200;   // suponemos que va a la izq.
            float escalaInicio = spriteUno.getScaleX()==1?1:3;
            float escalaFin = escalaInicio==1?3:1;
            if (pSceneTouchEvent.getX()>ANCHO_CAMARA/2) { // a la derecha?
                dx = 200;
            }
            // Se mueve
            MoveByModifier mover = new MoveByModifier(2,dx,dx/2);
            // Se escala
            ScaleModifier escalar = new ScaleModifier(2,escalaInicio,escalaFin);
            // Ahora ejecuta los dos en paralelo
            //ParallelEntityModifier modificador = new ParallelEntityModifier(mover,escalar);
            //SequenceEntityModifier modificador = new SequenceEntityModifier(mover,escalar);
            */
            // Ejecuta la acción definida por el modificador
            spriteUno.registerEntityModifier(modificador);
            return true;
        }
        return false;
    }
}


